# -*- coding: UTF-8 -*-

import re
from datetime import datetime
import sys
from sqlalchemy import and_,  func, or_
from typing import Dict, List, Any, Generator

from sqlalchemy import Boolean, Column, DateTime, Integer, String, Index, Table, ForeignKey, text, JSON, TEXT, DECIMAL, FLOAT
from sqlalchemy.orm import Session, relationship
from common.database import Base
from common.database import SessionMixin
from common.utils import is_empty
from core.logger import logger



__all__ = ['QosHostDisk']

class QosHostDisk(Base, SessionMixin):
    '''
    主机的磁盘信息
    '''
    __tablename__ = "qos_host_disk"
    quality_date = Column(String(64), nullable=False, index=True, comment='数据日期')
    instance_id = Column(String(128), nullable=False, index=True, comment='磁盘实例ID')
    host_instance_id = Column(String(128), nullable=False, index=True, comment='绑定主机实例ID')
    name = Column(String(128), nullable=False, index=True, comment='磁盘名')
    category = Column(String(32), nullable=False, comment='磁盘类型')
    size = Column(Integer, nullable=False, comment='磁盘大小')
    device = Column(String(32), nullable=False, comment='磁盘路径')
    tag = Column(String(64), nullable=False, comment='磁盘标签')
    instance_charge_type = Column(String(128), nullable=False, comment='磁盘付费类型')
    instance_price = Column(DECIMAL(10,2), nullable=False, comment='磁盘价格')
    # In_use使用中
    status = Column(String(16), nullable=False, comment='磁盘状态')
    cloud_platform = Column(String(64), nullable=False, comment='云平台')
    account_name = Column(String(128), nullable=False, comment='账号名称')

    update_at = Column(DateTime, nullable=False, default=datetime.now, onupdate=datetime.now, comment='更新时间')
    comment = Column(String(256), nullable=True, comment='备注说明')



    __table_args__ = (
        Index('idx_qos_host_disk_quality_date_instance_id', 'quality_date', 'instance_id', unique=True),
        {
            'mysql_engine': 'innodb',
            'mysql_charset': 'utf8mb4',
            'mysql_collate': 'utf8mb4_unicode_ci',
            'extend_existing': True,
            'mysql_row_format': 'dynamic'
        }
    )

    def __repr__(self):
        return f"<qos_service_info='{self.name}>"



    def object_to_dict(self, db: Session):
        result = {
            key: getattr(self, key)
            for key in self.__mapper__.c.keys()
        }
        
        from app.service_quality.models.qos_host_info import QosHostInfo
        result["host_info"] = QosHostInfo.get_info_by_instance_id(db, result["quality_date"], result["host_instance_id"])

        return result
    
    

    @classmethod
    def get_info_by_host_instance_id(cls, db: Session, quality_date: str, host_instance_id: str):
        objects_info = db.query(cls).filter(
            cls.quality_date == quality_date,
            cls.host_instance_id == host_instance_id
        ).to_dict()
        
        disk_info = [
            {
                "category": object_info["category"],
                "size": object_info["size"]
            }
            for object_info in objects_info
        ]
        
        return disk_info
    
    
    
    # 删除一个日期所有的数据，重新入库
    @classmethod
    def delete_by_quality_date(cls, db: Session, quality_date: str):
        db.query(cls).filter(
            cls.quality_date == quality_date
        ).delete()
        db.commit()
        
        
        
    
    # 日期内，根据field字段模糊查询value
    @classmethod
    def get_host_disk_search(cls, db: Session, quality_date: str, page: int, per_page: int, field: str, value: str):
        try:
            search_field = []
            display_field = cls.get_display_field()
            if value or field != "all":
                for key, col in cls.__table__.c.items():
                    if field == "all" or key == field:
                        search_field.append(col.like(f"%{value}%"))

            result = db.query(cls).filter(
                cls.quality_date == quality_date,
                or_(*search_field)
            ).with_entities(
                *display_field
            ).paginate(page=page, per_page=per_page)
        except Exception as e:
            logger.exception(f'{sys._getframe().f_code.co_name} {e}')
            return None

        # 每个字段的说明
        result["fields"] = cls.get_display_field_meta()

        return result
